Now I'm going to tell you 2 methods of making bots do non-bomb objectives,
activate triggers, teleport them, etc

Bots are untargeted by normal triggers and commands, but by using the 2 methods below,
we can define bots and use (not all) a lot of commands on them. Only a few are known atm.

Note that each method is used for a different purpose. The first is to make a bot trigger a trigger,
that makes him do a series of working commands or makes him undergo a series of working commands.

The second makes a bot use a trigger to complete unusual objectives, such as taking a documennt, 
contacting a radio...

=====================================================
=====================================================
		  Method 1
=====================================================
=====================================================

Spawnflags 12 is what makes all this work with bots!!

**********
  Usage
**********
If you want a bot to do something:

1. Set up trigger
------------------

	spawn trigger_(kind) "targetname" "(name)" "spawnflags" "12"
	$(name).origin = ( X X X )
	$(name) setsize ( -X -X -X ) ( X X X )
	$(name) setthread (threadname)

Fill in everything between the brackets.
Now let's continue to the real deal:


2. Set up setthread:
--------------------

(threadname):
local.ent = parm.other	//Defines the bot

end

In there, you can do as much as you want with that bot. 




****************************
  Commands, can and can't
****************************

Not working commands:
----------------------

A lot of commands which usually only apply to players now apply to bots.

**However there are a few player-specific (KNOWN) commands which don't apply to bots using this method:
	
	-tele			// teleports a player to a specified location
	-gravity		// sets the gravity of a player, if decreased and a player jumps, he'll jump higher and'll 'float' a bit


But there's a workaround ;) check the commands that do work!



Known commands which do work with bots using this method:
----------------------------------------------------------

	-if, while, switch statements
	-local.ent.dmteam = "(team)"  			//of course not spectator
	-local.ent.origin = ( X X X ) 			//This does the exact same thing as tele ;)
	-local.ent thread 				//you can use self in the executed thread as substitute for local.ent
	-local.thing attach local.ent "Bip01 Spine2" 0  //attach an object to any valid spot on the bot!
	-local.thing detach local.ent			//detach...no need to specify the location here
	-local.ent physics_off				//freeze bot
	-local.ent physics_on				//unfreeze bot
	-local.ent glue local.thing			//glue something to the bot or glue the bot to something
	-local.ent unglue local.thing
	-local.ent health X				//set the bots health, X being the value
	-local.thing = spawn script_origin		//Use this to set the gravity of a bot, spawn a script_origin
	 local.thing.origin = local.ent.origin		//glue it to the bot
	 local.ent glue local.thing
         local.thing gravity .1				//set the gravity to the script_origin
	-local.thing gravity 1				//Use this to set the gravity back to normal
	 local.thing remove				//you don't need the script_origin anymore




=====================================================
=====================================================
		Botscript method
=====================================================
=====================================================

In some cases, to make bots do an existing objective (! not a bomb but like documents, contacting radio's),
you must make a trigger_use (or multiple for some reason) in the .bot script and a triggernode targetting the trigger.


******************
 Setup botscript
******************

NOTE: You can only use this method if your botmap is botted using bdbodgers Botmapper tool!

EXAMPLE:
	//<------------------------------------------------------------->
	level.obj_model[108] = spawn trigger_use 			//for taking docs and contacting radio etc, you'd probably need a trigger_use
	level.obj_model[108].targetname = example_trigger		//targetname
	level.obj_model[108].origin = ( -932 3159 66 )			//same as the objective right?
	level.obj_model[108].angles = ( 0.000 0.000 0.000 )		//leave it 0, unimportant
	level.obj_model[108] setsize ( -50 -50 0 )( 50 50 50 )		//size of the trigger
	level.obj_model[108].triggerteam = none				//leave it none if you want to set it in the mapscript, else enter allies or axis
	level.obj_model[108].weight = 2.000				//'attraction value', the higher the more, leave it as it is, we must set this in the mapscript later
	//<------------------------------------------------------------->
	level.obj_model[109] = spawn info_pathnode			//DONT CHANGE
	level.obj_model[109].targetname = triggernode			//DONT CHANGE
	level.obj_model[109].origin = ( -932 3159 66 )			//same as trigger
	level.obj_model[109].angles = ( 0.000 180.000 0.000 )		//when the bot reaches this position, this is the direction he'll be facing
	level.obj_model[109].target = example_trigger			//MUST TARGET THE TRIGGER
	//<------------------------------------------------------------->

NOTE: Make sure the values [X] don't match any other value of the level.obj_model[] list in your .bot script!!!


******************
 Setup mapscript
******************

1. Set up botscript trigger properties:
---------------------------------------

If you haven't set the triggerteam in the botscript and left it none:
In the mapscript you set the triggerteam first after level waittill spawn:

	$(botscript_trigger_targetname).triggerteam = allies		//or axis

Then the weight:

	$(botscript_trigger_targetname).weight = 20

Now the setthread like this:

	$(botscript_trigger_targetname) thread (yoursetthread)





2. Stopping attraction
-----------------------

Strangely, the triggernode who targets the trigger is what attracts the bots. However it yields for the weight of the trigger itself.
But if the weight is 0, the triggernode will still attract bots. Using a big negative value will keep the bots away.

So when the objective is completed, 
you avoid deleting the trigger and you spare you 100kb of console spam by using this to keep the bots away.

	$(botscript_trigger_targetname).weight = -2000

This'll stop the trigger from attracting bots, any bots who were initially headed for the trigger will go somewhere else
if the bots got a camp or sniper spot or another triggernode. Sometimes some just stand still until shot and respawned and
some might even move after a while.




3. Set up setthread
--------------------

Of course when using this method, there are a lot less things a bot can do because there's no
spawnflags 12, and when you add it, spawnflags doesn't work.
But since this is only used for unusual objectives (like documents, contacting radio's) the bot doesn't need to know any tricks.

	(yoursetthread):
	self waittill trigger
	local.ent = self.other


4. Working Commands:
---------------------

Always start with that. Without the "self waittill trigger", this won't work. 
Known commands:
	-if statement
	-local.ent.dmteam = "(team)"  			//of course not spectator
	-local.ent.origin = ( X X X ) 			//This does the exact same thing as tele ;)
	-local.ent playsound 				//plays a small sound once

5. Examples and Important notes:
---------------------------------

	(yoursetthread):
	self waittill trigger
	local.ent = self.other
	if ( local.ent.dmteam == "allies" )
		{
		$(botscript_trigger_targetname) nottriggerable		//you don't want them to trigger it again after completion
		$(playertrigger_targetname) nottriggerable		//you don't want any player being able to trigger it after completion
		level.docs_taken++					//You'd probably need this for a winner check
		$documents hide						//Hides the documents, so it'll seem it's been picked up
		iprintln "The allies have taken the documents!"
		thread (threadname_ofyour_wincheck)			//You probably want to know if someone has won yet
		$(botscript_trigger_targetname).weight = -10000		//After completion, this stops bots from gathering near the trigger.
		}
	end


As you can see, you must think about a few things when setting a docs trigger, I'm also talking about maps without bots.
Players and bots can't 'take' the documents twice.



NOTE: Since your using a trigger for the objective for bots as well as player you must disable the bots trigger in the
trigger for the player. Because if a player completes the objective before a bot and you don't apply this, the bot will
"complete" the objective again.

So EXAMPLE:

	(playerstrigger_setthread):
	local.player = parm.other
	if ( local.player.dmteam == "allies" )
		{
		$(playertrigger_targetname) nottriggerable		
		$(botscript_trigger_targetname) nottriggerable		//you don't want bots completing the objective again
		$(botscript_trigger_targetname).weight = -10000		//you don't want bots gathering there
		level.docs_taken++
		$documents hide
		iprintln "The allies have taken the documents!"
		thread (threadname_ofyour_wincheck)
		}
	end






-------------------------------------------
-------------------------------------------
	EXTREMELY USEFUL STUFF
-------------------------------------------
-------------------------------------------
If your objective is a switch-objective(an objective where if in the process of being completed, the opposing team must try and undo it).
For example, the allies have to switch the radio on to send a message, the process takes 45 seconds, during those seconds, the axis have
the chance to stop the message from being sent. Then the allies try again etc...

-------------------------
   Switch triggerteam
-------------------------
Now it's very simple to do this.
When a team has turned the radio on, where you set the variable of the radio, (eg: level.radio_contacted = 1)
place this:

$(botscript_trigger).triggerteam = (axis/allies)

Do the same for the other team. This is switching "attraction" if the allies have done their job they leave and the axis get attracted to
stop them. If they stopped they allies, the axis leave and the allies are going to try again etc.


---------------------------------
   Making the teamswitch work
---------------------------------
Now, like this it won't work long. Because when the allies activated the trigger, and the axis are trying to deactivate it, nothing will happen.
Because the attraction may have switched of team but the trigger isn't that's why you need to refresh the triggers memory!!


!!! THERE ARE 2 METHODS

GOOD ONE:
---------
Refresh it by repeating it's setthread:  

$(botscript_trigger) thread (yoursetthread) 

behind the teamswitch bit. Now I experimented it and it appeared to stop working after 5 switches.
Maybe my fault but the next method is (till now) foolproof.



 The Foolproof ONE:
--------------------
Put your entire script between:

(yoursetthread):
while(1)
{
//your script


wait 0.15
}
end

NOTE: DO NOT USE end OR YOUR WHILE LOOPCHECK WILL STOP RIGHT AWAY, ONLY PUT end BEHIND THE CLOSING BRACKET OF while(1) AND IN A if/for/... 
statement, LIKE BELOW (read below!!)



  Don't forget !
-----------------
Of course, you must set another if statement between the brackets besides your teamswitch objective. Because if the objective is done, we 
don't need this anymore.
EXAMPLE:

if ( level.obj_complete == 1 )
	{
	$(botscript_trigger) nottriggerable
	$(human_trigger) nottriggerable
	$(botscript_trigger).weight = -2000
	end				//important to stop while(1)
	}



This is very similar to setting bombs. You can delay (like defusing) too, be creative.
Jv's botscript was originally designed to bot stock maps (with only bomb-type objectives) so all these other objectives weren't initially
supported. BUT it doesn't make them impossible (even before mine, cobs and prox' discoveries), on the contrary, 
I showed you they are quite possible.


------------------------------
 Objective Campnodes (switch
------------------------------
Now like objective, there are bombcamps, if the bomb isn't set, the defending team takes a spot or 2 around the bomb to defend.
If the bomb is set by the attacking team, they'll take those positions to make sure it stays set until explosion.
There are possibilities to solving this, similar to how I solved all other problems.

You might have noticed but all camper and sniper nodes have the same targetname. The following for statements, counts these, while the
if statements, identifies their tag and applies changes. Tags are similar to nametags, they tell us these nodes (with the same tags)
belong together in a "group" we've set.

EXAMPLE:
for(local.i = 1; local.i <= $camper.size; local.i++) 
{ 
if($camper[local.i].tag == tag1 ) 
	{
	$camper[local.i].noaxis = 1
	$camper[local.i].noallies = 0
	}
}

for(local.i = 1; local.i <= $sniper.size; local.i++) 
{ 
if( $sniper[local.i].tag == tag1 ) 
	{
	$sniper[local.i].noaxis = 1
	$sniper[local.i].noallies = 0
	}
}

You can place this in the same setthread I showed you earlier using while(1) (to refresh).


------------------------
 Disabling spawnpoints
------------------------
UNTESTED but should work; suggested by jv
Disabling spawnpoints (for new gametypes etc :D)
First, all spawnpoints have 2 targetnames: axisspawn and alliesspawn. 
Therefor we can't just disable anything because it'll disable all. So let's use our tag trick again:

	level.obj_model[402] = spawn script_origin
	level.obj_model[402].targetname = alliesspawn
	level.obj_model[402].origin = ( X X X )
	level.obj_model[402].angles = ( 0.000 96.000 0.000 )
	level.obj_model[402].tag = disableme


Then in your script, in the part where you want to disable the spawn:

for(local.i = 1; local.i <= $alliesspawn.size; local.i++) 
{ 
if($alliesspawn[local.i].tag == disableme )
	{
	$alliesspawn[local.i].disablespawn = 1
	}
} 


------------------------
   Setting botstats
------------------------
Since the destination of bots is determined the second a bot spawns, you can set special properties
to the node the bot is headed to so the bot'll enherit these. Spawn a campernode, snipernode, bombcamp...
And use on of these KNOWN and WORKING commands:

	level.obj_model[X].hearing = 1000
	level.obj_model[X].sight = 1000
	level.obj_model[X].gren_awareness = 150
	level.obj_model[X].accuracy = 150
	level.obj_model[X].ammo_grenade = 5
	level.obj_model[X].health = 120

Commands are simple to understand, no need for further explanations.
Replace the X with the number of the level.obj_model which spawns the info_pathnode (!!!!!)
EXAMPLE:

	level.obj_model[54] = spawn info_pathnode
	level.obj_model[54].targetname = sniper
	level.obj_model[54].origin = ( X X X )
	level.obj_model[54].angles = ( 0.000 0.000 0.000 )
	level.obj_model[54].target = so16
	level.obj_model[54].noaxis = 1
	level.obj_model[54].noallies = 0
	level.obj_model[54].weight = 1.000
	level.obj_model[54].nocrouch = 0
	//set special properties
	level.obj_model[54].hearing = 1000
	level.obj_model[54].sight = 1000

There are more commands, but they are still untested.



=====================================================
=====================================================
	Defining Bots outside of triggers
=====================================================
=====================================================
Of course all scripting is NOT done through triggers and you probably wonder how this can be done.
Similar to the player's counting system (for none triggers) this'll count and define bots. Though I still
haven't test what commands actually work. Glue works :p

To disable and enable weapons, just use the weaponpriorities bdbodger's botmapper generates and is set in all botmaps.
To give them all weapons..I don't know, I assume the same way as SP AI (or maybe the player way) but this could conflict with jv's scripts!


Bot counting system for non-trigger use:

//if (level.jvbot_jv_mp_ai_running == 1 && level.botlastid != NIL)
	if(level.botlastid != NIL)
	{
		for(local.i = 1; local.i <= level.botlastid; local.i++)
		{
			local.bot = level.actualbots[local.i]
			//script
		}
	}
end


I'll experiment further with what commands work in the first and the second method.